using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace usm.SolDev.DataBase.DataObjects.Experiment
{
    /// <summary>
    ///     The entity is an object described in .VSP file
    /// </summary>
    public class Entity : DataObject
    {
        #region Entity type enumeration
        public enum EntityType
        {
            etStore,    // %
            etTable,    // $
            etFacility, // #
            etVariable, // *
            etProcess,  // !
            etLabel     // &
        }
        #endregion

        #region Private fields
        private EntityType type;
        private string name = "";
        private int index;
        private bool monitored;
        private bool experiment;

        private bool isValid;

        #endregion

        #region Constructors
        /// <summary>
        ///     Default constructor
        /// </summary>
        public Entity () {}

        /// <summary>
        ///     Initialization and parsing constructor
        /// </summary>
        /// <param name="vspLine"></param>
        public Entity(string vspLine)
        {
            Match matchResult = null;
            matchResult = Regex.Match(vspLine, @"(?i)\s*(?<type>[%,$,#,*,!,&])\s+(?<name>[^\s]+)\s+(?<index>\b\d+\b)\s+(?<monitored>\b\d+\b)\s+(?<experiment>\b\d+\b)");
            if (matchResult != null && matchResult.Length > 0)
            {
                try
                {
                    #region Set the entity type
                    switch (matchResult.Result("${type}"))
                    {
                        case "%":
                            type = EntityType.etStore;
                            break;
                        case "$":
                            type = EntityType.etTable;
                            break;
                        case "#":
                            type = EntityType.etFacility;
                            break;
                        case "*":
                            type = EntityType.etVariable;
                            break;
                        case "!":
                            type = EntityType.etProcess;
                            break;
                        case "&":
                            type = EntityType.etLabel;
                            break;
                    }
                    #endregion

                    this.name = matchResult.Result("${name}");
                    index = int.Parse(matchResult.Result("${index}"));
                    monitored = (int.Parse(matchResult.Result("${monitored}")) != 0);
                    experiment = (int.Parse(matchResult.Result("${experiment}")) != 0);
                    isValid = true;

                }
                catch { }   // convert exceptions
            }

        }

        #region public properties

        /// <summary>
        ///     The entity type (described by type enumeration)
        /// </summary>
        public EntityType Type
        {
            get { return type; }
            set { type = value; }
        }
        /// <summary>
        ///     The entity name (found in the program)
        /// </summary>
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        /// <summary>
        ///     The index of the variable if it's an array (a table)
        /// </summary>
        public int Index
        {
            get { return index; }
            set { index = value; }
        }
        /// <summary>
        ///     The value is set to true if this entity is monitored
        /// </summary>
        public bool Monitored
        {
            get { return monitored; }
            set { monitored = value; }
        }
        /// <summary>
        ///     The value is set to true if global variable is used in experiment.
        /// </summary>
        public bool Experiment
        {
            get { return experiment; }
            set { experiment = value; }
        }

        /// <summary>
        ///     The property is set to true if passed VSP line has been parsed 
        /// without errors.
        /// </summary>
        public bool IsValid
        {
            get { return isValid; }
            set { isValid = value; }
        }

        #endregion

        #endregion

        #region Override standard ToStringMethod
        public override string ToString()
        {
            return name;
        }
        #endregion
    
    }
}
